package com.hnblc.blcwms.rest.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hnblc.blcwms.common.interaction.Response;
import com.hnblc.blcwms.persistent.interfaces.business.entity.*;
import com.hnblc.blcwms.persistent.interfaces.business.service.*;
import com.hnblc.blcwms.persistent.interfaces.client.entity.ClientAuth;
import com.hnblc.blcwms.serviceapi.api.dto.definition.ArticleCategory;
import com.hnblc.blcwms.serviceapi.api.dto.definition.ArticleInfo;
import com.hnblc.blcwms.serviceapi.api.dto.definition.BaseDefinition;
import com.hnblc.blcwms.serviceapi.api.dto.definition.Company;
import com.hnblc.blcwms.serviceapi.api.enums.result.definition.ArticleGroupResultEnum;
import com.hnblc.blcwms.serviceapi.api.enums.result.definition.ArticleInfoResultEnum;
import com.hnblc.blcwms.serviceapi.api.enums.result.definition.CompanyResultEnum;
import com.hnblc.blcwms.serviceapi.api.service.IDefinitionAPIService;
import com.hnblc.blcwms.serviceapi.definition.IBaseDefineService;
import com.hnblc.blcwms.serviceapi.definition.enums.code.ArticleGroupLevelEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class DefinitionAPIService implements IDefinitionAPIService {


    private Logger logger = LoggerFactory.getLogger(DefinitionAPIService.class);
    @Autowired
    IWmsArticlegroupService wmsArticlegroupService;

    @Autowired
    IWmsArticleService wmsArticleService;


    @Autowired
    IWmsOwnerService wmsOwnerService;

    @Autowired
    IWmsCustService wmsCustService;

    @Autowired
    IWmsSupplierService wmsSupplierService;

    @Autowired
    IBaseDefineService baseDefineService;

    @Override
    public Response createOwnerWithCustom(Company company) {
        Response result = this.createOwner(company);

        if (result.isSuccess()){
            company.setOwnerNo(company.getCompanyNo());
            result = this.createCustomForSell(company);
        }
        return result;
    }

    @Override
    public Response createOwner(Company company) {

        //验证货主是否存在
        if (baseDefineService.getOwnerCache(company.getCompanyNo())==null){
            return new Response(CompanyResultEnum.COMPANY_EXISTED);
        }
        //构造新增货主信息
        WmsOwner newOwner = this.buildWmsOwner(company);
        //构造货主接口同步权限信息
        ConvertOwnerSet ownerSet = new ConvertOwnerSet();
        ownerSet.setErpOwnerNo(company.getCompanyNo());
        ownerSet.setOwnerNo(company.getCompanyNo());
        ownerSet.setEnterpriseNo(company.getEnterpriseNo());
        //保存
        if (!wmsOwnerService.save(newOwner)){
            return new Response(CompanyResultEnum.SAVE_FAIL);
        }
        return new Response(CompanyResultEnum.SUCCESS);
    }


    private WmsOwner buildWmsOwner(Company company){
        WmsOwner newOwner = new WmsOwner();
        BeanUtils.copyProperties(company,newOwner);
        newOwner.setOwnerAddress(company.getCompanyAddress());
        newOwner.setOwnerNo(company.getCompanyNo());
        newOwner.setOwnerName(company.getCompanyName());
        newOwner.setEnterpriseNo(company.getEnterpriseNo());
        newOwner.setOwnerContact(company.getCompanyContact());
        newOwner.setOwnerPhone(company.getCompanyPhone());
        newOwner.setOwnerFax(company.getCompanyFax());
        newOwner.setNotes(company.getCompanyRemark());
        newOwner.setStatus(1.00);
        newOwner.setOwnerAlias(company.getCompanyAlias());
        newOwner.setHandletime(LocalDateTime.now());
        newOwner.setSheetid(company.getSheetId());
        return newOwner;
    }
    @Override
    public Response createCustomForSell(Company company) {
        //验证货主代码是否存在
        if (baseDefineService.getOwnerCache(company.getOwnerNo())==null){
            return new Response(CompanyResultEnum.UNKNOWN_OWNER_NO);
        }
        //验证客户代码是否已存在
        if (baseDefineService.getCustCashe(company.getEnterpriseNo(),company.getOwnerNo(),company.getCompanyNo())!=null){
            return new Response(CompanyResultEnum.COMPANY_EXISTED);
        }
        //验证创建单是否已在缓存区
        if (wmsCustService.getOne(new QueryWrapper<WmsCust>().eq("owner_no",company.getOwnerNo())
                .eq("enterprise_no",company.getEnterpriseNo())
                .eq("owner_cust_no",company.getCompanyNo())
                .eq("sheetid",company.getSheetId()))!=null){
            return new Response(CompanyResultEnum.SHEET_EXISTED);
        }
        //构造客户信息
        WmsCust newCustom = this.buildWmsCust(company);

        //构造客户接口传单权限信息
        ConvertCustSet custSet = new ConvertCustSet();
        custSet.setEnterpriseNo(company.getEnterpriseNo());
        custSet.setCustNo(company.getCompanyNo());
        custSet.setErpCustNo(company.getCompanyNo());
        custSet.setOwnerCustNo(company.getCompanyNo());
        custSet.setSubCustNo(company.getCompanyNo());
        if (!wmsCustService.saveOrUpdate(newCustom)){
            return new Response(CompanyResultEnum.SAVE_FAIL);
        }
        return new Response(CompanyResultEnum.SUCCESS);
    }

    private WmsCust buildWmsCust(Company company){
        WmsCust newCust = new WmsCust();
        BeanUtils.copyProperties(company,newCust);
        newCust.setAddress(company.getCompanyAddress());
        newCust.setOwnerCustNo(company.getCompanyNo());
        newCust.setCustName(company.getCompanyName());
        newCust.setCustType(0);
        newCust.setEnterpriseNo(company.getEnterpriseNo());
        newCust.setLinkman(company.getCompanyContact());
        newCust.setTele(company.getCompanyPhone());
        newCust.setEMail(company.getCompanyEmail());
        newCust.setFax(company.getCompanyFax());
        newCust.setNotes(company.getCompanyRemark());
        newCust.setStatus(1);
        newCust.setManager(company.getCompanyContact());
        newCust.setSheetid(company.getSheetId());
        return newCust;
    }

    @Override
    public Response createSupplier(Company company) {
        //验证货主代码是否存在
        if (baseDefineService.getOwnerCache(company.getOwnerNo())==null){
            return new Response(CompanyResultEnum.UNKNOWN_OWNER_NO);
        }
        //验证供应商代码是否存在
        if (baseDefineService.getSupplierCashe(company.getOwnerNo(),company.getCompanyNo())!=null){
            return new Response(CompanyResultEnum.COMPANY_EXISTED);
        }

        //验证创建单是否已在缓存区
        if (wmsSupplierService.getOne(new QueryWrapper<WmsSupplier>().eq("owner_no",company.getOwnerNo())
                .eq("supplier_no",company.getCompanyNo())
                .eq("sheetid",company.getSheetId()))!=null){
            return new Response(CompanyResultEnum.SHEET_EXISTED);
        }
        WmsSupplier newSupplier = this.buildWmsSupplier(company);

        if (!wmsSupplierService.save(newSupplier)){
            return new Response(CompanyResultEnum.SAVE_FAIL);
        }
        return new Response(CompanyResultEnum.SUCCESS);
    }

    private WmsSupplier buildWmsSupplier(Company company){
        WmsSupplier newSupplier = new WmsSupplier();
        BeanUtils.copyProperties(company,newSupplier);
        newSupplier.setAddress(company.getCompanyAddress());
        newSupplier.setSupplierNo(company.getCompanyNo());
        newSupplier.setSupplierName(company.getCompanyName());
        newSupplier.setEnterpriseNo(company.getEnterpriseNo());
        newSupplier.setLinkman(company.getCompanyContact());
        newSupplier.setPhone(company.getCompanyPhone());
        newSupplier.setEMail(company.getCompanyEmail());
        newSupplier.setFax(company.getCompanyFax());
        newSupplier.setNotes(company.getCompanyRemark());
        newSupplier.setStatus(1.00);
        newSupplier.setManager(company.getCompanyContact());
        newSupplier.setSheetid(company.getSheetId());

        return newSupplier;
    }
    @Override
    public Response<List<ArticleCategory>> createCategories(BaseDefinition<List<ArticleCategory>> categorieData, ClientAuth clientAuth) {

        if (categorieData.getDefinitionData().size()<1){
            return new Response<>(ArticleGroupResultEnum.EMPTY_ARRAY);
        }
        List<WmsArticlegroup> articleGroups = new ArrayList<>();
        String sheetid = categorieData.getSheetId();
        Set<String> codeSet = new HashSet();
        for (ArticleCategory level1Category:categorieData.getDefinitionData()){
            //构造一级类别
            articleGroups.add(this.buildWmsArticleGroup(level1Category, ArticleGroupLevelEnum.ONE,level1Category.getCategoryCode(),sheetid,clientAuth));
            //验证重复
            if (codeSet.contains(level1Category.getCategoryCode())){
                return new Response<>(ArticleGroupResultEnum.REPEAT_CATEGORY);
            }else {
                codeSet.add(level1Category.getCategoryCode());
            }
            if (level1Category.getCategories()!=null && level1Category.getCategories().size()>0){
                for (ArticleCategory level2Category:level1Category.getCategories()) {
                    //构造二级类别
                    articleGroups.add(this.buildWmsArticleGroup(level2Category, ArticleGroupLevelEnum.TWO,level1Category.getCategoryCode(),sheetid,clientAuth));
                    //验证重复
                    if (codeSet.contains(level2Category.getCategoryCode())){
                        return new Response<>(ArticleGroupResultEnum.REPEAT_CATEGORY);
                    }else {
                        codeSet.add(level2Category.getCategoryCode());
                    }
                    if (level2Category.getCategories()!=null){
                        for (ArticleCategory level3Category:level2Category.getCategories()) {
                            //构造三级类别
                            articleGroups.add(this.buildWmsArticleGroup(level3Category, ArticleGroupLevelEnum.THREE,level2Category.getCategoryCode(),sheetid,clientAuth));
                            //验证重复
                            if (codeSet.contains(level3Category.getCategoryCode())){
                                return new Response<>(ArticleGroupResultEnum.REPEAT_CATEGORY);
                            }else {
                                codeSet.add(level3Category.getCategoryCode());
                            }
                        }
                    }
                }
            }
        }
        if (articleGroups.size()<1){
            return new Response<>(ArticleGroupResultEnum.READ_FAIL);
        }
        if (!wmsArticlegroupService.saveOrUpdateBatch(articleGroups)){
            logger.error("Error occurred when save article categories sheetid:"+categorieData.getSheetId());
            return new Response<>(ArticleGroupResultEnum.SAVE_FAIL);
        }
        return new Response<>(ArticleGroupResultEnum.SUCCESS);
    }

    /**
     * 根据商品类别报文bean创建持久化bean
     * @param articleCategory 类别报文bean
     * @param levelCode 类别级别
     * @param parentCode 父类别
     * @param sheetid 创建唯一单号
     * @param clientAuth 货主授权信息
     * @return
     */
    private WmsArticlegroup buildWmsArticleGroup(ArticleCategory articleCategory,ArticleGroupLevelEnum levelCode,String parentCode,String sheetid,ClientAuth clientAuth){
        WmsArticlegroup articleGroup = new WmsArticlegroup();

        articleGroup.setEnterpriseNo(clientAuth.getEnterpriseNo());
        articleGroup.setOwnerNo(clientAuth.getOwnerNo());
        articleGroup.setGroupNo(articleCategory.getCategoryCode());
        articleGroup.setGroupName(articleCategory.getCategoryName());
        articleGroup.setLevelid(Double.valueOf(levelCode.code()));
        articleGroup.setHeadgroupNo(parentCode);
        articleGroup.setHandletime(LocalDateTime.now());
        articleGroup.setSheetid(sheetid);
        return articleGroup;
    }
    @Override
    public Response<List<ArticleInfo>> createArticleInfos(BaseDefinition<List<ArticleInfo>> articleInfos, ClientAuth clientAuth) {
        List<WmsArticle> articles = new ArrayList<>();
        if (articleInfos.getDefinitionData().size()<1){
            return new Response<>(ArticleInfoResultEnum.EMPTY_ARRAY);
        }
        List<ArticleInfo> errorArticles = new ArrayList<>();
        for (ArticleInfo articleInfo: articleInfos.getDefinitionData()){

            if (baseDefineService.getSupplierCashe(clientAuth.getOwnerNo(),articleInfo.getSupplierNo())==null){
                articleInfo.setErrorReason(MessageFormat.format(ArticleInfoResultEnum.SINGLE_SUPPLIER_NOT_FOUND.getMessage(),articleInfo.getSupplierNo()));

                errorArticles.add(articleInfo);
            }
            articles.add(this.buildArticleInfo(articleInfo,articleInfos.getSheetId(),clientAuth));
        }

        if (errorArticles.size()>0){
            return new Response<>(ArticleInfoResultEnum.SUPPLIER_NOT_FOUND,errorArticles);
        }

        if (articles.size()<1){
            return new Response<>(ArticleInfoResultEnum.READ_FAIL);
        }
        if (!wmsArticleService.saveBatch(articles)){
            logger.error("Error occurred when save article categories sheetid:"+articleInfos.getSheetId());
            return new Response<>(ArticleInfoResultEnum.SAVE_FAIL);
        }
        return new Response<>(ArticleInfoResultEnum.SUCCESS);
    }


    private WmsArticle buildArticleInfo(ArticleInfo articleInfo,String sheetid,ClientAuth clientAuth){
        WmsArticle wmsArticle = new WmsArticle();
        BeanUtils.copyProperties(articleInfo,wmsArticle);
        wmsArticle.setSheetid(sheetid);
        wmsArticle.setOwnerNo(clientAuth.getOwnerNo());
        wmsArticle.setEnterpriseNo(clientAuth.getEnterpriseNo());
        wmsArticle.setHandletime(LocalDateTime.now());

        return wmsArticle;
    }


}
